package com.enki.cigarettes.controller;

import com.enki.cigarettes.controller.vo.response.OrderDetailResponseVo;
import com.enki.cigarettes.controller.vo.response.OrderItemResponseVo;
import com.enki.cigarettes.controller.vo.response.OrderResponseVo;
import com.enki.cigarettes.entity.*;
import com.enki.cigarettes.enums.*;
import com.enki.cigarettes.handler.Response;
import com.enki.cigarettes.repository.*;
import com.enki.cigarettes.statics.StaticKeys;
import com.enki.cigarettes.utils.DateUtils;
import com.enki.cigarettes.utils.PrimaryKey;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @author WCS.Wang
 * @version V1.0
 * @Package com.enki.cigarettes.controller
 * @Name e-cigarettes-shop-api-module
 * @Description: TODO 我的订单
 * @date 2019-07-21
 */
@RestController
@RequestMapping("/api/my/orders")
@Slf4j
public class MyOrderController {

    @Autowired
    OrderTRepository orderTRepository;
    @Autowired
    OrderItemTRepository orderItemTRepository;
    @Autowired
    TradeSnapshotTRepository tradeSnapshotTRepository;
    @Autowired
    UserTRepository userTRepository;
    @Autowired
    CouponTRepository couponTRepository;
    @Autowired
    UserCouponTRepository userCouponTRepository;
    @Autowired
    BalanceHistoryTRepository balanceHistoryTRepository;


    @ApiOperation(value = "查询全部订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int"),
            @ApiImplicitParam(name = "size", value = "每页数据", required = true, dataType = "int"),
            @ApiImplicitParam(name = "selectType", value = "查询类型", required = true, dataType = "int")
    })
    @GetMapping
    public Object findByPage(@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size, @RequestParam(value = "selectType", defaultValue = "0") int selectType, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            Sort sort = new Sort(Sort.Direction.DESC, StaticKeys.SORT_CREATE_TIME);
            Pageable pageable = PageRequest.of(page, size, sort);
            Specification<OrderT> specification = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    if (selectType == 1) { // 待付款
                        predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.UNPAID.getStatus()));
                    } else if (selectType == 2) { // 待发货
//                        predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("orderStatus"), OrderEnums.OrderStatus.PAID.getStatus()));
//                        predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("orderStatus"), OrderEnums.OrderStatus.SIGNING.getStatus()));
                        predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.PAID.getStatus()));
                    } else if (selectType == 3) { // 待签收
                        predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.SHIPPED.getStatus()));
                    } else if (selectType == 4) { // 待评价
                        predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.SIGNING.getStatus()));
                        predicateList.add(criteriaBuilder.equal(root.get("commentStatus"), CommentEnums.CommentStatus.PENDING.getStatus()));
                    }
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            Page<OrderT> beanPage = orderTRepository.findAll(specification, pageable);
            List<OrderResponseVo> vos = new ArrayList<>();
            for (OrderT bean : beanPage.getContent()) {
                OrderResponseVo vo = new OrderResponseVo();
                vo.setOrderPaymenId(bean.getOrderPaymenId());
                vo.setOrderId(bean.getId());
                vo.setDeliverAddress(bean.getDeliverAddress());
                vo.setOrderAmountTotal(bean.getOrderAmountTotal());
                vo.setPayMethod(PaymentEnums.PaymentChannel.ALIPAY.getName());
                vo.setOrderStatus(bean.getOrderStatus());
                vo.setCreateTime(DateUtils.getDateYMDHMS(bean.getCreateTime()));
                vo.setCommentStatus(bean.getCommentStatus());
                // 订单类目
                List<OrderItemT> orderItemList = orderItemTRepository.findByOrderTId(bean.getId());
                List<OrderItemResponseVo> items = new ArrayList<>();
                int quantity = 0;
                for (OrderItemT orderItem : orderItemList) {
                    TradeSnapshotT tradeSnapshot = tradeSnapshotTRepository.findByOrderTIdAndOrderItemTId(bean.getId(), orderItem.getId());
                    OrderItemResponseVo item = new OrderItemResponseVo();
                    item.setProductId(orderItem.getProductTId() + "");
                    item.setName(tradeSnapshot.getName());
                    item.setSkuPicture(tradeSnapshot.getSkuPicture());
                    item.setProductPrice(orderItem.getProductPrice());
                    item.setQuantity(orderItem.getQuantity());
                    item.setProductSkuName(orderItem.getProductSkuName());
                    items.add(item);
                    quantity += orderItem.getQuantity();
                }
                // 订单子类ID--当订单商品item数量为1时，此字段有效
                if (orderItemList.size() == 1) {
                    vo.setOrderItemId(orderItemList.get(0).getId());
                }
                vo.setQuantity(quantity);
                vo.setOrderItems(items);
                vos.add(vo);
            }
            responseData.put("content", vos);
            responseData.put("number", beanPage.getNumber());
            responseData.put("totalPages", beanPage.getTotalPages());
            responseData.put("totalElements", beanPage.getTotalElements());
            responseData.put("size", beanPage.getSize());
            responseData.put("last", beanPage.isLast());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取全部订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取全部订单失败");
        }
    }

    @ApiOperation(value = "查询待支付订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int"),
            @ApiImplicitParam(name = "size", value = "每页数据", required = true, dataType = "int")
    })
    @GetMapping(value = "/unpaid")
    public Object findUnpaidByPage(@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            Sort sort = new Sort(Sort.Direction.DESC, StaticKeys.SORT_CREATE_TIME);
            Pageable pageable = PageRequest.of(page, size, sort);
            Specification<OrderT> specification = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.UNPAID.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            Page<OrderT> beanPage = orderTRepository.findAll(specification, pageable);
            List<OrderResponseVo> vos = new ArrayList<>();
            int quantity = 0;
            for (OrderT bean : beanPage.getContent()) {
                OrderResponseVo vo = new OrderResponseVo();
                vo.setOrderPaymenId(bean.getOrderPaymenId());
                vo.setOrderId(bean.getId());
                vo.setDeliverAddress(bean.getDeliverAddress());
                vo.setOrderAmountTotal(bean.getOrderAmountTotal());
                vo.setPayMethod(PaymentEnums.PaymentChannel.ALIPAY.getName());
                vo.setOrderStatus(bean.getOrderStatus());
                vo.setCreateTime(DateUtils.getDateYMDHMS(bean.getCreateTime()));
                vo.setCommentStatus(bean.getCommentStatus());
                // 订单类目
                List<OrderItemT> orderItemList = orderItemTRepository.findByOrderTId(bean.getId());
                List<OrderItemResponseVo> items = new ArrayList<>();
                for (OrderItemT orderItem : orderItemList) {
                    TradeSnapshotT tradeSnapshot = tradeSnapshotTRepository.findByOrderTIdAndOrderItemTId(bean.getId(), orderItem.getId());
                    OrderItemResponseVo item = new OrderItemResponseVo();
                    item.setProductId(orderItem.getProductTId() + "");
                    item.setName(tradeSnapshot.getName());
                    item.setSkuPicture(tradeSnapshot.getSkuPicture());
                    item.setProductPrice(orderItem.getProductPrice());
                    item.setQuantity(orderItem.getQuantity());
                    item.setProductSkuName(orderItem.getProductSkuName());
                    items.add(item);
                    quantity += orderItem.getQuantity();
                }
                vo.setQuantity(quantity);
                vo.setOrderItems(items);
                vos.add(vo);
            }
            responseData.put("content", vos);
            responseData.put("number", beanPage.getNumber());
            responseData.put("totalPages", beanPage.getTotalPages());
            responseData.put("totalElements", beanPage.getTotalElements());
            responseData.put("size", beanPage.getSize());
            responseData.put("last", beanPage.isLast());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取全部订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取全部订单失败");
        }
    }


    @ApiOperation(value = "查询待发货订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int"),
            @ApiImplicitParam(name = "size", value = "每页数据", required = true, dataType = "int")
    })
    @GetMapping(value = "/paid")
    public Object findPaidByPage(@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            Sort sort = new Sort(Sort.Direction.DESC, StaticKeys.SORT_CREATE_TIME);
            Pageable pageable = PageRequest.of(page, size, sort);
            Specification<OrderT> specification = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.PAID.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            Page<OrderT> beanPage = orderTRepository.findAll(specification, pageable);
            List<OrderResponseVo> vos = new ArrayList<>();
            for (OrderT bean : beanPage.getContent()) {
                OrderResponseVo vo = new OrderResponseVo();
                vo.setOrderPaymenId(bean.getOrderPaymenId());
                vo.setOrderId(bean.getId());
                vo.setDeliverAddress(bean.getDeliverAddress());
                vo.setOrderAmountTotal(bean.getOrderAmountTotal());
                vo.setPayMethod(PaymentEnums.PaymentChannel.ALIPAY.getName());
                vo.setOrderStatus(bean.getOrderStatus());
                vo.setCreateTime(DateUtils.getDateYMDHMS(bean.getCreateTime()));
                vo.setCommentStatus(bean.getCommentStatus());
                // 订单类目
                List<OrderItemT> orderItemList = orderItemTRepository.findByOrderTId(bean.getId());
                List<OrderItemResponseVo> items = new ArrayList<>();
                int quantity = 0;
                for (OrderItemT orderItem : orderItemList) {
                    TradeSnapshotT tradeSnapshot = tradeSnapshotTRepository.findByOrderTIdAndOrderItemTId(bean.getId(), orderItem.getId());
                    OrderItemResponseVo item = new OrderItemResponseVo();
                    item.setProductId(orderItem.getProductTId() + "");
                    item.setName(tradeSnapshot.getName());
                    item.setSkuPicture(tradeSnapshot.getSkuPicture());
                    item.setProductPrice(orderItem.getProductPrice());
                    item.setQuantity(orderItem.getQuantity());
                    item.setProductSkuName(orderItem.getProductSkuName());
                    items.add(item);
                    quantity += orderItem.getQuantity();
                }
                vo.setQuantity(quantity);
                vo.setOrderItems(items);
                vos.add(vo);
            }
            responseData.put("content", vos);
            responseData.put("number", beanPage.getNumber());
            responseData.put("totalPages", beanPage.getTotalPages());
            responseData.put("totalElements", beanPage.getTotalElements());
            responseData.put("size", beanPage.getSize());
            responseData.put("last", beanPage.isLast());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取待发货订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取待发货订单失败");
        }
    }

    @ApiOperation(value = "查询待收货订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int"),
            @ApiImplicitParam(name = "size", value = "每页数据", required = true, dataType = "int")
    })
    @GetMapping(value = "/shipped")
    public Object findShippedByPage(@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            Sort sort = new Sort(Sort.Direction.DESC, StaticKeys.SORT_CREATE_TIME);
            Pageable pageable = PageRequest.of(page, size, sort);
            Specification<OrderT> specification = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.SHIPPED.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            Page<OrderT> beanPage = orderTRepository.findAll(specification, pageable);
            List<OrderResponseVo> vos = new ArrayList<>();
            for (OrderT bean : beanPage.getContent()) {
                OrderResponseVo vo = new OrderResponseVo();
                vo.setOrderPaymenId(bean.getOrderPaymenId());
                vo.setOrderId(bean.getId());
                vo.setDeliverAddress(bean.getDeliverAddress());
                vo.setOrderAmountTotal(bean.getOrderAmountTotal());
                vo.setPayMethod(PaymentEnums.PaymentChannel.ALIPAY.getName());
                vo.setOrderStatus(bean.getOrderStatus());
                vo.setCreateTime(DateUtils.getDateYMDHMS(bean.getCreateTime()));
                vo.setCommentStatus(bean.getCommentStatus());
                // 订单类目
                List<OrderItemT> orderItemList = orderItemTRepository.findByOrderTId(bean.getId());
                List<OrderItemResponseVo> items = new ArrayList<>();
                int quantity = 0;
                for (OrderItemT orderItem : orderItemList) {
                    TradeSnapshotT tradeSnapshot = tradeSnapshotTRepository.findByOrderTIdAndOrderItemTId(bean.getId(), orderItem.getId());
                    OrderItemResponseVo item = new OrderItemResponseVo();
                    item.setProductId(orderItem.getProductTId() + "");
                    item.setName(tradeSnapshot.getName());
                    item.setSkuPicture(tradeSnapshot.getSkuPicture());
                    item.setProductPrice(orderItem.getProductPrice());
                    item.setQuantity(orderItem.getQuantity());
                    item.setProductSkuName(orderItem.getProductSkuName());
                    items.add(item);
                    quantity += orderItem.getQuantity();
                }
                vo.setQuantity(quantity);
                vo.setOrderItems(items);
                vos.add(vo);
            }
            responseData.put("content", vos);
            responseData.put("number", beanPage.getNumber());
            responseData.put("totalPages", beanPage.getTotalPages());
            responseData.put("totalElements", beanPage.getTotalElements());
            responseData.put("size", beanPage.getSize());
            responseData.put("last", beanPage.isLast());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取全部订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取全部订单失败");
        }
    }

    @ApiOperation(value = "查询待评价订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "int"),
            @ApiImplicitParam(name = "size", value = "每页数据", required = true, dataType = "int")
    })
    @GetMapping(value = "/comment")
    public Object findCommentOrderByPage(@RequestParam(value = "page", defaultValue = "0") int page, @RequestParam(value = "size", defaultValue = "10") int size, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            Sort sort = new Sort(Sort.Direction.DESC, StaticKeys.SORT_CREATE_TIME);
            Pageable pageable = PageRequest.of(page, size, sort);
            Specification<OrderT> specification = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.SIGNING.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("commentStatus"), CommentEnums.CommentStatus.PENDING.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            Page<OrderT> beanPage = orderTRepository.findAll(specification, pageable);
            List<OrderResponseVo> vos = new ArrayList<>();
            for (OrderT bean : beanPage.getContent()) {
                OrderResponseVo vo = new OrderResponseVo();
                vo.setOrderPaymenId(bean.getOrderPaymenId());
                vo.setOrderId(bean.getId());
                vo.setDeliverAddress(bean.getDeliverAddress());
                vo.setOrderAmountTotal(bean.getOrderAmountTotal());
                vo.setPayMethod(PaymentEnums.PaymentChannel.ALIPAY.getName());
                vo.setOrderStatus(bean.getOrderStatus());
                vo.setCreateTime(DateUtils.getDateYMDHMS(bean.getCreateTime()));
                vo.setCommentStatus(bean.getCommentStatus());
                // 订单类目
                List<OrderItemT> orderItemList = orderItemTRepository.findByOrderTId(bean.getId());
                List<OrderItemResponseVo> items = new ArrayList<>();
                int quantity = 0;
                for (OrderItemT orderItem : orderItemList) {
                    TradeSnapshotT tradeSnapshot = tradeSnapshotTRepository.findByOrderTIdAndOrderItemTId(bean.getId(), orderItem.getId());
                    OrderItemResponseVo item = new OrderItemResponseVo();
                    item.setProductId(orderItem.getProductTId() + "");
                    item.setName(tradeSnapshot.getName());
                    item.setSkuPicture(tradeSnapshot.getSkuPicture());
                    item.setProductPrice(orderItem.getProductPrice());
                    item.setQuantity(orderItem.getQuantity());
                    item.setProductSkuName(orderItem.getProductSkuName());
                    items.add(item);
                    quantity += orderItem.getQuantity();
                }
                vo.setQuantity(quantity);
                vo.setOrderItems(items);
                vos.add(vo);
            }
            responseData.put("content", vos);
            responseData.put("number", beanPage.getNumber());
            responseData.put("totalPages", beanPage.getTotalPages());
            responseData.put("totalElements", beanPage.getTotalElements());
            responseData.put("size", beanPage.getSize());
            responseData.put("last", beanPage.isLast());
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取全部订单失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取全部订单失败");
        }
    }

    @ApiOperation(value = "获取订单详情")
    @ApiImplicitParam(name = "id", value = "订单ID", required = true, dataType = "String")
    @GetMapping(value = "/{id}")
    public Object findOne(@PathVariable String id, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            OrderT order = orderTRepository.findOneByIdAndUserTIdAndRemoved(id, sessionId.toString(), StaticKeys.REMOVED);
            if (order == null) {
                return Response.notFound_404("不存在的订单信息，请核实");
            }
            if (order.getOrderStatus() == OrderEnums.OrderStatus.UNPAID.getStatus()) {
                // 待付款
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.PAID.getStatus()) {
                // 已付款
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.SHIPPED.getStatus()) {
                // 已发货
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.SIGNING.getStatus()) {
                // 已签收
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.RETURN_APPLICATION.getStatus()) {
                // 退货申请
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.RETURN.getStatus()) {
                // 退货中
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.RETURNED.getStatus()) {
                // 已退货
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.TRANSACTION_CANCEL.getStatus()) {
                // 取消交易
            } else if (order.getOrderStatus() == OrderEnums.OrderStatus.TRANSACTION_COMPLETE.getStatus()) {
                // 交易完成
            }
            OrderDetailResponseVo vo = new OrderDetailResponseVo();
            vo.setOrderId(order.getId());
            vo.setDeliverAddress(order.getDeliverAddress());
            vo.setOrderAmountTotal(order.getOrderAmountTotal());
            vo.setPayMethod(PaymentEnums.PaymentChannel.getName(order.getPaymentChannel()));
            vo.setOrderStatus(order.getOrderStatus());
            vo.setCreateTime(DateUtils.getDateYMDHMS(order.getCreateTime()));
            vo.setStoreDiscount(order.getStoreDiscount());
            vo.setPlatformDiscount(order.getPlatformDiscount());
            vo.setProductAmountTotal(order.getProductAmountTotal());
            vo.setLogisticsCode(order.getLogisticsCode());
            vo.setLogisticsName(order.getLogisticsName());
            vo.setFareTotal(order.getFareTotal());
            vo.setTax(order.isIsTax());
            vo.setWelfare(order.getBenefits());
            vo.setOrderPaymenId(order.getOrderPaymenId());
            if (order.isIsTax()) {
                vo.setInvoiceContent(order.getInvoiceContent());
            }
            vo.setUserRemark(order.getUserRemark());
            // 订单类目
            List<OrderItemT> orderItemList = orderItemTRepository.findByOrderTId(order.getId());
            List<OrderItemResponseVo> items = new ArrayList<>();
            for (OrderItemT orderItem : orderItemList) {
                TradeSnapshotT tradeSnapshot = tradeSnapshotTRepository.findByOrderTIdAndOrderItemTId(order.getId(), orderItem.getId());
                OrderItemResponseVo item = new OrderItemResponseVo();
                item.setProductId(orderItem.getProductTId() + "");
                item.setName(tradeSnapshot.getName());
                item.setSkuPicture(tradeSnapshot.getSkuPicture());
                item.setProductPrice(orderItem.getProductPrice());
                item.setQuantity(orderItem.getQuantity());
                item.setProductSkuName(orderItem.getProductSkuName());
                item.setProductId(orderItem.getProductTId() + "");
                item.setCommentStatus(true);
                items.add(item);
            }
            vo.setOrderItems(items);
            return Response.success(vo, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取订单详情失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取订单详情失败");
        }
    }


    @ApiOperation(value = "订单数量统计")
    @GetMapping(value = "/statistics")
    public Object statistics(HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            Map<String, Object> responseData = new HashMap<>();
            Specification<OrderT> specificationAll = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            // 总量
            long all = orderTRepository.count(specificationAll);

            Specification<OrderT> specificationUniPaid = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.UNPAID.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            // 待支付
            long unpaid = orderTRepository.count(specificationUniPaid);

            Specification<OrderT> specificationConduct = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.PAID.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            // 进行中
            long conduct = orderTRepository.count(specificationConduct);

            Specification<OrderT> specificationFinish = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.SHIPPED.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            // 已完成
            long finish = orderTRepository.count(specificationFinish);

            Specification<OrderT> specificationComment = new Specification<OrderT>() {
                @Override
                public Predicate toPredicate(Root<OrderT> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> predicateList = new ArrayList<>();
                    predicateList.add(criteriaBuilder.equal(root.get("userTId"), sessionId.toString()));
                    predicateList.add(criteriaBuilder.equal(root.get("orderStatus"), OrderEnums.OrderStatus.SIGNING.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("commentStatus"), CommentEnums.CommentStatus.PENDING.getStatus()));
                    predicateList.add(criteriaBuilder.equal(root.get("removed"), StaticKeys.REMOVED));
                    Predicate[] predicates = new Predicate[predicateList.size()];
                    query.where(predicateList.toArray(predicates));
                    return query.getRestriction();
                }
            };
            // 待评价
            long comment = orderTRepository.count(specificationComment);
            responseData.put("all", all);
            responseData.put("unpaid", unpaid);
            responseData.put("conduct", conduct);
            responseData.put("finish", finish);
            responseData.put("comment", comment);
            return Response.success(responseData, StaticKeys.SUCCESS);
        } catch (Exception e) {
            log.error("获取订单统计信息失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，获取订单统计信息失败");
        }
    }

    @ApiOperation(value = "确认收货")
    @ApiImplicitParam(name = "id", value = "订单ID", required = true, dataType = "String")
    @GetMapping(value = "/received/{id}")
    @Transactional
    public Object receivedOrder(@PathVariable String id, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            UserT userBean = userTRepository.findOneById(sessionId.toString());
            if (userBean == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            OrderT order = orderTRepository.findOneByIdAndUserTIdAndRemoved(id, sessionId.toString(), StaticKeys.REMOVED);
            if (order == null) {
                return Response.notFound_404("不存在的订单，请核实");
            }
            if (order.getOrderStatus() == OrderEnums.OrderStatus.SHIPPED.getStatus()) {
                // 已签收
                order.setOrderStatus(OrderEnums.OrderStatus.SIGNING.getStatus());
                orderTRepository.save(order);
                // 判断是否为首单
                if (order.isFirstOrder()) {
                    // 退换首单支付金额
                    /**
                     * 订单返利最多40元，系统中钱的单位为：分
                     */
                    int orderAmountTotal = 4000;
                    if (order.getOrderAmountTotal() <= 4000) {
                        orderAmountTotal = order.getOrderAmountTotal();
                    }
                    // 余额变化，金额单位为分
                    // 处理用户余额
                    int curBalance = userBean.getCurBalance() + orderAmountTotal;
                    userBean.setCurBalance(curBalance);
                    // 记录余额变化历史
                    BalanceHistoryT balanceHistory = new BalanceHistoryT();
                    balanceHistory.setId(PrimaryKey.get().toString());
                    balanceHistory.setBalanceAmountTotal(curBalance);
                    balanceHistory.setBalanceStatus(BalanceEnums.BalanceStatus.REBATE.getStatus());
                    balanceHistory.setSubTotal(orderAmountTotal);
                    balanceHistory.setUserTId(userBean.getId());
                    balanceHistory.setRemark("来自订单" + order.getId() + "的返利");
                    balanceHistory.setCreateTime(new Date());
                    userTRepository.save(userBean);
                    balanceHistoryTRepository.save(balanceHistory);

                    // 如果是被邀请，送邀请人优惠券
                    // 邀请码
                    if (StringUtils.isNotBlank(userBean.getInviteeCode())) {
                        /**
                         * 赠送邀请人20元优惠券、10元返利
                         */
                        UserT invitationCodeUser = userTRepository.findOneByInvitationCode(userBean.getInviteeCode());
                        if (invitationCodeUser != null) {
                            CouponT coupon = new CouponT();
                            coupon.setId(PrimaryKey.get().toString());
                            if (userBean.getUserSource() == UserEnums.UserSource.CHINESE.getSource()) {
                                coupon.setCouponName("邀请新人券");
                            } else {
                                coupon.setCouponName("Newcomer Invitation Ticket");
                            }
                            coupon.setCouponCount(1);
                            coupon.setType(0);
                            coupon.setCouponStint(-1);
                            // 优惠金额
                            coupon.setCouponPrice(2000);
                            // 使用说明
                            coupon.setRemark("订单结算时使用");
                            coupon.setEffectiveStartTime(new Date());
                            coupon.setEffectiveEndTime(DateUtils.getNextYearDay());
                            coupon.setCouponScope(0);
                            coupon.setStoreId(StaticKeys.NULL);
                            coupon.setCouponMoney(6900);
                            coupon.setCouponAmount(0);
                            coupon.setStatus(true);
                            coupon.setCreateTime(new Date());
                            coupon.setUpdateTime(new Date());
                            coupon.setPicture(StaticKeys.NULL);
                            couponTRepository.save(coupon);

                            // 保存用户优惠券信息
                            UserCouponT userCoupon = new UserCouponT();
                            userCoupon.setId(PrimaryKey.get().toString());
                            userCoupon.setUserId(invitationCodeUser.getId());
                            userCoupon.setCouponTId(coupon.getId());
                            userCoupon.setDataId(StaticKeys.NULL);
                            userCoupon.setStatus(false);
                            userCoupon.setCreateTime(new Date());
                            userCouponTRepository.save(userCoupon);

                            /**
                             *  保存邀请返利
                             *  余额变化，金额单位为分
                             */
                            // 处理用户余额
                            int inviteeCurBalance = invitationCodeUser.getCurBalance() + 1000;
                            invitationCodeUser.setCurBalance(curBalance);
                            // 记录余额变化历史
                            BalanceHistoryT inviteeBalanceHistory = new BalanceHistoryT();
                            inviteeBalanceHistory.setId(PrimaryKey.get().toString());
                            inviteeBalanceHistory.setBalanceAmountTotal(inviteeCurBalance);
                            inviteeBalanceHistory.setBalanceStatus(BalanceEnums.BalanceStatus.INVITATION.getStatus());
                            inviteeBalanceHistory.setSubTotal(1000);
                            inviteeBalanceHistory.setUserTId(invitationCodeUser.getId());
                            inviteeBalanceHistory.setRemark("来自邀请好友返利");
                            inviteeBalanceHistory.setCreateTime(new Date());
                            userTRepository.save(invitationCodeUser);
                            balanceHistoryTRepository.save(inviteeBalanceHistory);
                        }
                    }
                }
            }
            return Response.success();
        } catch (Exception e) {
            log.error("确认收货失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，确认收货失败");
        }
    }

    @ApiOperation(value = "删除订单")
    @ApiImplicitParam(name = "id", value = "订单ID", required = true, dataType = "String")
    @DeleteMapping(value = "/{id}")
    public Object del(@PathVariable String id, HttpSession session) {
        try {
            Object sessionId = session.getAttribute(StaticKeys.USER_ID);
            if (sessionId == null) {
                return Response.unauthorized_401("登录身份失效，请重新登录");
            }
            OrderT order = orderTRepository.findOneByIdAndUserTIdAndRemoved(id, sessionId.toString(), StaticKeys.REMOVED);
            if (order == null) {
                return Response.notFound_404("不存在的订单，请核实");
            }
            if (order.getOrderStatus() == OrderEnums.OrderStatus.UNPAID.getStatus() ||
                    order.getOrderStatus() == OrderEnums.OrderStatus.SIGNING.getStatus() ||
                    order.getOrderStatus() == OrderEnums.OrderStatus.TRANSACTION_CANCEL.getStatus() ||
                    order.getOrderStatus() == OrderEnums.OrderStatus.TRANSACTION_COMPLETE.getStatus()) {
                // 订单状态标记为删除
                order.setRemoved(true);
                orderTRepository.save(order);
            }
            return Response.success();
        } catch (Exception e) {
            log.error("确认收货失败：" + e.getMessage());
            e.printStackTrace();
            return Response.serverError_500("服务器错误，确认收货失败");
        }
    }

}
